#include <iostream>
#include <pthread.h>
#include <unistd.h>
#include <string.h>
#include <thread>


// 线程的局部存储
// __thread只能修饰内置类型，表示每个线程都私有一份
__thread int shared_value = 100;

std::string toHex(pthread_t tid)
{
    // 4. 进程内的函数，线程共享
    char buffer[64];
    snprintf(buffer, sizeof(buffer), "0x%lx", tid);
    return buffer;
}

void *start(void *args)
{
    std::string name = static_cast<const char *>(args);
    sleep(1);
    while (true)
    {
        printf("I am a new thread, name: %s, shared_value: %d,  &shared_value: %p\n", name.c_str(), shared_value, &shared_value);
        sleep(1);
    }

    return nullptr;
}

int main()
{
    pthread_attr_t attr;

    
    pthread_t tid;
    pthread_create(&tid, nullptr, start, (void *)"thread-1");
    std::cout << "I am a new thread, name: main, " << toHex(pthread_self())
              << ", NEW thread id: " << toHex(tid) << std::endl;

    while (true)
    {
        printf("main thread, shared_value: %d,  &shared_value: %p\n", shared_value, &shared_value);
        shared_value += 10;
        sleep(1);
    }
    pthread_join(tid, nullptr);
    return 0;
}




// int *addr = nullptr; // 获取线程中栈的数据的地址，也就是说另一个线程可以拿到这个线程的栈中的数据，也就是理论上线程栈也是共享的
// void *start1(void *args)
// {
//     std::string name = static_cast<const char *>(args);
//     int a = 100;
//     addr = &a;
//     while (true)
//     {
//         std::cout << name << " local val a: " << a << std::endl;
//         sleep(1);
//     }
// }

// void *start2(void *args)
// {
//     std::string name = static_cast<const char *>(args);
//     int a = 100;
//     while (true)
//     {
//         if (addr != nullptr)
//             std::cout << name << " mod val a: " << (*addr)++ << std::endl;
//         sleep(1);
//     }
// }
// void *start(void *args)
// {
//     //如果想要进程替换，不可以直接进程替换，不然整个进程的代码和数据就被替换了，就会导致线程崩溃
//     //可以通过fork来创建子进程进行exec
//     // pid_t id = fork();
//     // if(id == 0)
//     // {
//     //     // ....
//     // }
//     std::string name = static_cast<const char *>(args);
//     pthread_detach(pthread_self());
//     while (true)
//     {
//         std::cout << "I am a new thread" << std::endl;
//         sleep(1);
//     }
//     //return 0;
//     //exit(0);//表示进程退出
//     //pthread_exit((void*)10);
// }


// int main()
// {
//     pthread_t tid;
//     pthread_create(&tid, nullptr, start, (void *)"thread-1");
//     std::cout << "tid: " << tid << std::endl;
//     sleep(5);
//     // int m = pthread_cancel(tid);
//     // std::cout << "取消线程: " << tid << std::endl;
//     // int m = pthread_detach(tid);
//     // if(m != 0)
//     // std::cout << "detach error" << std::endl;
//     int n = pthread_join(tid, nullptr);//pthread_detach(tid)之后，join就会失败  
//     if (n != 0)
//     {
//         std::cerr << "join error: " << n << ", " << strerror(n) << std::endl;
//         return 1;
//     }
//     void* ret = nullptr;
//     pthread_join(tid, &ret);//PTHREAD_CANCELED，线程被取消的返回值,#define PTHREAD_CANCELED ((void *) -1)
//     std::cout << "new thread exit code: " << (long long int)ret << std::endl; //(long long int)ret
    



//     // void* ret = nullptr;
//     // int n = pthread_join(tid, (void**)(&ret));
//     // std::cout << "new thread exit code: " << (long long int)ret << " ,n: " << n << std::endl; //(long long int)ret
//     // if (n != 0)
//     // {
//     //     std::cerr << "join error: " << n << ", " << strerror(n) << std::endl;
//     //     return 1;
//     // }

//     sleep(5);
//     while(true)
//     {
//         std::cout << "我是主线程"  << std::endl;
//         sleep(1);
//     }
//     // pthread_t tid1,tid2;
//     // pthread_create(&tid1,nullptr,start1,(void*)"thread-1");
//     // pthread_create(&tid2,nullptr,start2,(void*)"thread-1");

//     // pthread_join(tid1,nullptr);
//     // pthread_join(tid2,nullptr);

//     return 0;
// }

// class ThreadData
// {
// public:
//     ThreadData()
//     {
//     }
//     void Init(const std::string &name, int a, int b)
//     {
//         _name = name;
//         _a = a;
//         _b = b;
//     }
//     void Excute() { _result = _a + _b; }
//     int Result() { return _result; }
//     std::string Name() { return _name; }
//     void SetId(pthread_t tid) { _tid = tid; }
//     pthread_t Id() { return _tid; }
//     int A() { return _a; }
//     int B() { return _b; }
//     ~ThreadData()
//     {
//     }

// private:
//     std::string _name;
//     pthread_t _tid;
//     int _result;
//     int _b;
//     int _a;
// };
// int gval = 100;
// std::string toHex(pthread_t tid)
// {
//     char buffer[1024];
//     snprintf(buffer, sizeof(buffer), "0x%lx", tid);
//     return buffer;
// }
// void *run2(void *args)
// {
//     std::string name = static_cast<const char *>(args);
//     while (true)
//     {
//         std::cout << "我是新线程，我的名字是" << name << "，my tid is : " << toHex(pthread_self()) << "，全局变量（会修改），" << gval << std::endl;
//         sleep(1);
//         // 线程出现异常，可能会导致其他线程全部崩溃
//         int *p = nullptr;
//         *p = 10;
//     }
//     return nullptr;
// }

// void *run(void *args)
// {
//     // std::string name = static_cast<const char *>(args);
//     ThreadData *td = static_cast<ThreadData *>(args);

//     while (true)
//     {
//         std::cout << "我是新线程，我的名字是" << td->Name() << "，my tid is : " << toHex(pthread_self()) << "，全局变量（会修改），" << gval << std::endl;
//         gval++;
//         td->Excute();
//         sleep(1);
//         break;
//     }
//     // return nullptr;
//     // int *p = new int(10);
//     // return (void*)p; // 线程退出方式1：线程入口函数return，表示线程退出
//     return td;
// }

// #define NUM 10
// int main()
// {
//     ThreadData t[NUM];
//     for (int i = 0; i < NUM; i++)
//     {
//         char id[64];
//         snprintf(id, sizeof(id), "thread-%d", i);
//         t[i].Init(id, i * 10, i * 20);
//     }
//     // 创建多线程
//     for (int i = 0; i < NUM; i++)
//     {
//         pthread_t id;
//         pthread_create(&id, nullptr, run, &t[i]);
//         t[i].SetId(id);
//     }

//     // 等待多线程
//     for (int i = 0; i < NUM; i++)
//     {
//         int n = pthread_join(t[i].Id(), nullptr);
//         if (n != 0)
//         {
//             std::cerr << "join error: " << n << ", " << strerror(n) << std::endl;
//             return 1;
//         }
//         std::cout << "join success!, ret: " << std::endl;
//     }

//     // 汇总处理结果
//     for (int i = 0; i < NUM; i++)
//     {
//         printf("td[%d]: %d+%d=%d[%ld]\n", i, t[i].A(), t[i].B(), t[i].Result(), t[i].Id());
//     }

//     // pthread_t tid1;
//     // ThreadData *td = new ThreadData();
//     // td->Init("thread-1", 100, 20);
//     // pthread_create(&tid1, nullptr, run, td);
//     // ThreadData *rtd = nullptr;
//     // int n = pthread_join(tid1, (void**)&rtd);

//     // if(n != 0)
//     // {
//     //     std::cerr << "join error: " << n << ", " << strerror(n) << std::endl;
//     //     return 1;
//     // }
//     // std::cout << "join success!, ret: " << rtd->Result() << std::endl;
//     // delete td;

//     // pthread_t tid1;
//     // pthread_create(&tid1, nullptr, run, (void *)"thread-1");
//     // pthread_t tid2;
//     // pthread_create(&tid2, nullptr, run, (void *)"thread-2");
//     // pthread_t tid3;
//     // pthread_create(&tid3, nullptr, run, (void *)"thread-3");
//     // pthread_t tid4;
//     // sleep(3);
//     // pthread_create(&tid4, nullptr, run2, (void *)"thread-4");

//     // printf("new thread id: 0x%lx\n", tid1);
//     // printf("new thread id: 0x%lx\n", tid2);
//     // printf("new thread id: 0x%lx\n", tid3);
//     // printf("new thread id: 0x%lx\n", tid4);

//     while (true)
//     {
//         sleep(1);
//         std::cout << "我是main线程..." << "，my tid is : " << toHex(pthread_self()) << "，全局变量（会修改），" << gval << std::endl;
//     }
//     return 0;
// }

// void* run(void* arg)
// {
//     std::string name = static_cast<const char*>(arg);
//     while(true)
//     {
//         std::cout << "我是新线程，我的名字是" << name << std::endl;
//         sleep(1);
//     }
//     return nullptr;
// }
// int main()
// {
//     std::thread t([](const char* name){
//         while(true)
//         {
//             std::cout << "我是新线程，我的名字是，" << name << std::endl;
//             sleep(1);
//         }
//     },"new thread");
//     while(true)
//     {
//         sleep(1);
//         std::cout << "我是主线程" << std::endl;
//     }
//     // pthread_t tid;
//     // int n = pthread_create(&tid,nullptr,run,(void*)"thread-1");
//     // if(n != 0)
//     // {
//     //     std::cout << "create new thread error : " << strerror(n) << std::endl;
//     //     return 1;
//     // }
//     // while(true)
//     // {
//     //     sleep(1);
//     //     std::cout << "我是主线程" << std::endl;
//     // }
//     return 0;
// }